﻿@{
    // 표준 시간대에 대한 일부 시간 변수 저장
    var now = Time.NowInLocal;

    // 요청 변수(쿼리 문자열) 가져오기
    // 설정된 경우 세션에 저장합니다.

    if (!Request["year"].IsEmpty()) {
        Session["Year"] = Request["year"].AsInt();
    }
    if (!Request["month"].IsEmpty()) {
        Session["Month"] = Request["month"].AsInt();
    }

    // 세션에 아무 것도 없으면 연도를 가져옵니다. 현재 항목이 필요합니다.
    int year = Session["Year"] != null ? (int)Session["Year"] : now.Year;
    int month = Session["Month"] != null ? (int)Session["Month"] : now.Month;

    // 월의 첫 번째 날을 가져옵니다.
    var firstDayOfMonth = new DateTime(year, month, 1);

    var previousMonth = firstDayOfMonth.AddDays(-1);
    var daysInPreviousMonth = DateTime.DaysInMonth(previousMonth.Year, previousMonth.Month);

    var numberOfDaysInMonth = DateTime.DaysInMonth(year, month);

    // 다음 달 첫 번째 날의 자정 아침: 4/1/2010 12:00:00 AM
    var lastDayOfMonth = firstDayOfMonth.AddDays(numberOfDaysInMonth);

    var dayOfWeek = firstDayOfMonth.DayOfWeek;

    // 필요한 공백 셀의 개수
    var numBlankCells =  (int)dayOfWeek;

    // 새 행을 만들 시점을 알기 위해 사용합니다. (%7)
    var dayCounter = 1;

    // 이달의 현재 날짜입니다.
    var dayNumber = 1;

    var db = UserHelper.DatabaseInstance;

    var events = db.Query(@"SELECT
                            e.Id, e.Name, e.AllDay, e.Start, e.[End], cu.Color, e.Don
                            FROM Events AS e
                            JOIN Calendars AS c ON e.CalendarID = c.Id
                            JOIN CalendarsUsers AS cu ON c.Id = cu.CalendarId
                            JOIN Users AS u ON cu.UserId = u.Id
                            WHERE u.Id = @0
                            AND e.Start >= @1
                            AND e.[End] <= @2",
                        WebSecurity.CurrentUserId,
                        firstDayOfMonth,
                        lastDayOfMonth
                        );

    var dayGroups =
        (from dynamic e in (IEnumerable<object>)events
        group e by Time.UtcToLocal(e.Start).Date into g
        orderby g.Key
        select new { 
            Date = g.Key, 
            Events = g.OrderByDescending(e => e.AllDay).ThenBy(e => e.Start)
        }).ToDictionary(g => g.Date.Day);

    var dayGroupIndex = 0;
}

<table class="month-view">
    <caption>
        <a href="?year=@(previousMonth.Year)&amp;month=@(previousMonth.Month)" title="이전 달">&laquo;</a>
        @firstDayOfMonth.ToString("MMMM")
        <a href="?year=@(lastDayOfMonth.Year)&amp;month=@(lastDayOfMonth.Month)" title="다음 달">&raquo;</a>
        <span style="float: right"><a href="?year=@(now.Year)&amp;month=@(now.Month)">오늘</a></span>
    </caption>
    <thead>
        <tr>
            <th scope="col">일요일</th>
            <th scope="col">월요일</th>
            <th scope="col">화요일</th>
            <th scope="col">수요일</th>
            <th scope="col">목요일</th>
            <th scope="col">금요일</th>
            <th scope="col">토요일</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            @* 정확한 날에 시작할 수 있도록 모든 공백 인쇄*@
            @for (int i = numBlankCells-1; i >= 0; i--) {
                <td class="inactive">
                    <span class="day-number">
                        @(daysInPreviousMonth-i)
                    </span>
                </td>
                dayCounter++;
            }

            @* 이달의 모든 날짜를 확인 *@
            @while (dayNumber <= numberOfDaysInMonth) {
                string className = "";
                if (dayNumber == now.Day && year == now.Year && month == now.Month) {
                    className = "today";
                }
                <td class="@className">
                    <span class="day-number">@dayNumber</span>                

                    @* 날짜 집합에 현재 날짜의 이벤트가 포함된 경우 *@
                    @if (dayGroups.ContainsKey(dayNumber)) {
                        @RenderPage(Themes.GetResourcePath("Partials", "DayList.cshtml"), dayGroups[dayNumber].Events, false)
                        dayGroupIndex++;
                    }

                </td>
                dayCounter++;
                dayNumber++;
                @* 주말인 경우 다음 행으로 이동 *@
                if (dayCounter % 8 == 0 && dayNumber -1 != numberOfDaysInMonth) {
                    @:</tr><tr>
                    dayCounter++;
                }
            }
            @* 이번주 표시 종료 *@
            @{
                dayNumber = 1;
                while (dayCounter % 8 > 1 && dayCounter %8 <= 7) {
                    <td class="inactive">
                       <span class="day-number">@dayNumber</span>
                    </td>
                    dayNumber++;
                    dayCounter++;
                }
            }
        </tr>
    </tbody>
</table>